<template>
  <div class="process-progress-diagram" ref="diagramContainer">
    <div class="diagram-header">
      <div class="header-info">
        <h4 class="diagram-title">
          <el-icon><Connection /></el-icon>
          流程执行进度图
        </h4>
        <div class="progress-summary">
          <span class="progress-text">进度: {{ progressPercentage }}%</span>
          <el-progress 
            :percentage="progressPercentage" 
            :color="progressColor"
            :stroke-width="6"
            style="width: 200px;"
          />
        </div>
      </div>
      
      <!-- 工具栏 -->
      <div class="diagram-toolbar">
        <el-button 
          size="small" 
          type="primary" 
          :icon="FullScreen" 
          @click="toggleFullscreen"
        >
          {{ isFullscreen ? '退出全屏' : '全屏查看' }}
        </el-button>
        <el-button 
          size="small" 
          :icon="Refresh" 
          @click="refreshDiagram"
        >
          刷新
        </el-button>
      </div>
      
      <!-- 图例 -->
      <div class="diagram-legend">
        <div class="legend-item">
          <div class="legend-color pending"></div>
          <span>未开始</span>
        </div>
        <div class="legend-item">
          <div class="legend-color current"></div>
          <span>进行中</span>
        </div>
        <div class="legend-item">
          <div class="legend-color completed"></div>
          <span>已完成</span>
        </div>
        <div class="legend-item">
          <div class="legend-color rejected"></div>
          <span>已拒绝</span>
        </div>
      </div>
    </div>
    
    <div class="diagram-content" :style="{ height: diagramHeight + 'px' }">
      <div class="canvas-content">
        <!-- 流程节点 -->
        <div
          v-for="node in processNodes"
          :key="node.id"
          class="progress-node"
          :class="[
            `node-${node.type.toLowerCase()}`,
            `status-${node.status}`,
            { 'has-execution-info': node.executionInfo }
          ]"
          :style="{
            left: node.position.x + 'px',
            top: node.position.y + 'px'
          }"
          @click="handleNodeClick(node)"
        >
          <div class="node-header">
            <div class="node-icon-wrapper">
              <el-icon class="node-icon">
                <component :is="getNodeIcon(node.type)" />
              </el-icon>
              <!-- 状态指示器 -->
              <div class="status-indicator">
                <el-icon v-if="node.status === 'completed'" class="status-icon completed">
                  <Check />
                </el-icon>
                <el-icon v-else-if="node.status === 'rejected'" class="status-icon rejected">
                  <Close />
                </el-icon>
                <el-icon v-else-if="node.status === 'current'" class="status-icon current">
                  <Loading />
                </el-icon>
                <el-icon v-else class="status-icon pending">
                  <Clock />
                </el-icon>
              </div>
            </div>
            <div class="node-info">
              <span class="node-title">{{ node.name }}</span>
              <span class="node-id">{{ node.id }}</span>
              <!-- 显示审批节点的处理人 -->
              <span v-if="node.type === 'APPROVAL' && node.assigneeDisplayName" class="node-assignee">
                {{ node.assigneeDisplayName }}
              </span>
            </div>
          </div>
          
          <!-- 执行信息 -->
          <div v-if="node.executionInfo && node.executionInfo.endTime" class="execution-info">
            <!-- 只有已完成的节点才显示执行信息 -->
            <div class="execution-row">
              <el-icon><Timer /></el-icon>
              <span>{{ formatDuration(node.executionInfo.duration) }}</span>
            </div>
            <div v-if="node.executionInfo.operator" class="execution-row">
              <el-icon><User /></el-icon>
              <span>{{ node.executionInfo.operatorName || getOperatorDisplayName(node.executionInfo.operator) }}</span>
            </div>
          </div>
          
          <!-- 审批节点的待审批人员信息（当节点进行中时显示审批人） -->
          <div v-if="node.type === 'APPROVAL' && node.status === 'current' && node.assigneeDisplayName" class="assignee-info">
            <div class="assignee-row">
              <el-icon><User /></el-icon>
              <span>{{ node.assigneeDisplayName }}</span>
            </div>
          </div>
          
          <!-- 节点状态标签 -->
          <div class="node-status-badge">
            <el-tag 
              :type="getStatusTagType(node.status)" 
              size="small"
              class="status-tag"
            >
              {{ getStatusText(node.status) }}
            </el-tag>
          </div>
        </div>

        <!-- 连接线 -->
        <svg 
          class="flows-svg" 
          :width="canvasSize.width" 
          :height="canvasSize.height"
        >
          <defs>
            <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
              <polygon points="0 0, 10 3.5, 0 7" fill="#d1d5db" />
            </marker>
            <marker id="arrowhead-completed" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
              <polygon points="0 0, 10 3.5, 0 7" fill="#10b981" />
            </marker>
            <marker id="arrowhead-current" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
              <polygon points="0 0, 10 3.5, 0 7" fill="#3b82f6" />
            </marker>
          </defs>
          
          <!-- 流程连接线 -->
          <path
            v-for="flow in processFlows"
            :key="flow.id"
            :d="getFlowPath(flow)"
            :stroke="getFlowColor(flow)"
            :stroke-width="getFlowWidth(flow)"
            fill="none"
            :marker-end="getFlowMarker(flow)"
            class="flow-line"
            :class="flow.status"
          />
        </svg>
      </div>
    </div>
    
    <!-- 节点详情弹窗 -->
    <el-dialog
      v-model="showNodeDetail"
      :title="`节点执行详情 - ${selectedNode?.name}`"
      width="600px"
      @close="closeNodeDetail"
    >
      <div v-if="selectedNode" class="node-detail-content">
        <!-- 节点基本信息 -->
        <div class="detail-section">
          <h4>基本信息</h4>
          <el-descriptions :column="2" border>
            <el-descriptions-item label="节点名称">
              {{ selectedNode.name }}
            </el-descriptions-item>
            <el-descriptions-item label="节点ID">
              {{ selectedNode.id }}
            </el-descriptions-item>
            <el-descriptions-item label="节点类型">
              {{ getNodeTypeName(selectedNode.type) }}
            </el-descriptions-item>
            <el-descriptions-item label="执行状态">
              <el-tag :type="getStatusTagType(selectedNode.status)">
                {{ getStatusText(selectedNode.status) }}
              </el-tag>
            </el-descriptions-item>
          </el-descriptions>
        </div>

        <!-- 执行详情 -->
        <div v-if="selectedNode.executionInfo" class="detail-section">
          <h4>执行详情</h4>
          <el-descriptions :column="1" border>
            <el-descriptions-item label="开始时间">
              {{ formatTime(selectedNode.executionInfo.startTime) }}
            </el-descriptions-item>
            <el-descriptions-item label="结束时间">
              {{ formatTime(selectedNode.executionInfo.endTime) }}
            </el-descriptions-item>
            <el-descriptions-item label="执行耗时">
              {{ formatDuration(selectedNode.executionInfo.duration) }}
            </el-descriptions-item>
            <el-descriptions-item label="操作人">
              {{ selectedNode.executionInfo.operatorName || selectedNode.executionInfo.operator || '-' }}
            </el-descriptions-item>
            <el-descriptions-item label="操作备注">
              <div class="comment-content">
                {{ selectedNode.executionInfo.comment || '-' }}
              </div>
            </el-descriptions-item>
          </el-descriptions>
        </div>

        <!-- 无执行记录 -->
        <div v-else class="no-execution-info">
          <el-empty description="暂无执行记录" />
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { 
  Check, Close, Loading, Clock, Timer, User, Connection, 
  VideoPlay, Document, FullScreen, Refresh
} from '@element-plus/icons-vue'
import { userApi } from '@/api/user'

// 用户相关类型定义
interface User {
  id: number
  username: string
  realName?: string
  email?: string
}

// Props 定义
interface ProcessNode {
  id: string
  name: string
  type: string
  position: { x: number; y: number }
  status: 'pending' | 'current' | 'completed' | 'rejected'
  assignee?: string | number
  assigneeDisplayName?: string
  executionInfo?: {
    startTime?: string
    endTime?: string
    duration?: number
    operator?: string
    operatorName?: string
    comment?: string
    nodeName?: string
    nodeType?: string
  }
}

interface ProcessFlow {
  id: string
  from: string
  to: string
  name?: string
  condition?: string
  status: 'pending' | 'active' | 'completed'
}

interface Props {
  processDefinition: {
    id: string
    name: string
    key: string
    jsonDef: string
  }
  taskHistory: any[]
  currentNodeId?: string
  processStatus: number
  instanceId?: string
}

const props = defineProps<Props>()

// 响应式数据
const diagramContainer = ref<HTMLElement>()
const showNodeDetail = ref(false)
const selectedNode = ref<ProcessNode | null>(null)
const diagramHeight = ref(500)
const canvasSize = reactive({ width: 1200, height: 500 })
const isFullscreen = ref(false)
const userMap = ref<Map<number, User>>(new Map()) // 用户ID到用户信息的映射

// 计算属性
const processNodes = computed(() => {
  try {
    const definition = JSON.parse(props.processDefinition.jsonDef)
    const nodes = definition.nodes || []
    
    return nodes.map((node: any) => {
      const nodeStatus = getNodeStatus(node.id)
      const executionInfo = getNodeExecutionInfo(node.id)
      
      // 处理审批节点的assignee显示
      let assigneeDisplayName: string | null = null
      if (node.type === 'APPROVAL' && node.assignee) {
        console.log(`[流程进度图] 审批节点 ${node.name}, assignee=${node.assignee}, assigneeType=${node.assigneeType}`)
        assigneeDisplayName = getOperatorDisplayName(node.assignee)
        console.log(`[流程进度图] 解析后的审批人名称: ${assigneeDisplayName}`)
      }
      
      const result = {
        id: node.id,
        name: node.name || node.id,
        type: node.type,
        position: calculateNodePosition(node, nodes),
        status: nodeStatus,
        executionInfo,
        assignee: node.assignee,
        assigneeDisplayName
      }
      
      console.log(`[流程进度图] 节点 ${node.name} 完整数据:`, result)
      
      return result
    })
  } catch (error) {
    console.error('解析流程定义失败:', error)
    return []
  }
})

const processFlows = computed(() => {
  try {
    const definition = JSON.parse(props.processDefinition.jsonDef)
    const flows = definition.flows || []
    
    return flows.map((flow: any) => ({
      id: flow.id || `${flow.from}-${flow.to}`,
      from: flow.from,
      to: flow.to,
      name: flow.name,
      condition: flow.condition,
      status: getFlowStatus(flow)
    }))
  } catch (error) {
    console.error('解析流程连接失败:', error)
    return []
  }
})

const progressPercentage = computed(() => {
  const totalNodes = processNodes.value.length
  if (totalNodes === 0) return 0
  
  const completedNodes = processNodes.value.filter(node => 
    node.status === 'completed'
  ).length
  
  return Math.round((completedNodes / totalNodes) * 100)
})

const progressColor = computed(() => {
  if (props.processStatus === 2) return '#67c23a' // 已完成 - 绿色
  if (progressPercentage.value >= 80) return '#409eff' // 进行中高进度 - 蓝色
  if (progressPercentage.value >= 50) return '#e6a23c' // 进行中中进度 - 橙色
  return '#f56c6c' // 进行中低进度 - 红色
})

// 方法
const getNodeStatus = (nodeId: string) => {
  if (!props.taskHistory || props.taskHistory.length === 0) {
    // 根据流程状态和当前节点推断
    if (props.processStatus === 2) {
      return 'completed'
    } else if (nodeId === props.currentNodeId) {
      return 'current'
    }
    return 'pending'
  }
  
  // 精确匹配（优先使用，避免误匹配）
  let nodeActivity = props.taskHistory.find(activity => activity.nodeId === nodeId)
  
  // 仅对特殊节点进行模糊匹配（START和END节点）
  // 注意：审批节点不进行模糊匹配，避免将未执行的审批节点误判为已完成
  if (!nodeActivity) {
    if (nodeId === 'end' || (nodeId.startsWith('end_') && nodeId.includes('end'))) {
      nodeActivity = props.taskHistory.find(activity => 
        activity.nodeId === 'end' || 
        activity.nodeType === 'END'
      )
    } else if (nodeId === 'start' || (nodeId.startsWith('start_') && nodeId.includes('start'))) {
      nodeActivity = props.taskHistory.find(activity => 
        activity.nodeId === 'start' || 
        activity.nodeType === 'START'
      )
    }
    // 对于其他类型的节点（如审批节点、条件分支节点），不进行模糊匹配
    // 必须精确匹配nodeId，这样可以确保只有真正执行过的节点才会显示为已完成
  }
  
  if (nodeActivity) {
    if (nodeActivity.endTime) {
      // 检查是否被拒绝
      if (nodeActivity.comment && 
          (nodeActivity.comment.includes('驳回') || 
           nodeActivity.comment.includes('拒绝') || 
           nodeActivity.comment.includes('reject'))) {
        return 'rejected'
      }
      return 'completed'
    }
    if (nodeActivity.startTime && !nodeActivity.endTime) {
      return 'current'
    }
  }
  
  // 没有找到对应的历史记录，说明该节点未被执行
  return 'pending'
}

const getNodeExecutionInfo = (nodeId: string) => {
  if (!props.taskHistory || props.taskHistory.length === 0) {
    return null
  }
  
  // 精确匹配（优先使用，避免误匹配）
  let nodeActivity = props.taskHistory.find(activity => activity.nodeId === nodeId)
  
  // 仅对特殊节点进行模糊匹配（START和END节点）
  // 注意：审批节点不进行模糊匹配，避免将未执行的审批节点误判为已完成
  if (!nodeActivity) {
    if (nodeId === 'end' || (nodeId.startsWith('end_') && nodeId.includes('end'))) {
      nodeActivity = props.taskHistory.find(activity => 
        activity.nodeId === 'end' || 
        activity.nodeType === 'END'
      )
    } else if (nodeId === 'start' || (nodeId.startsWith('start_') && nodeId.includes('start'))) {
      nodeActivity = props.taskHistory.find(activity => 
        activity.nodeId === 'start' || 
        activity.nodeType === 'START'
      )
    }
    // 对于其他类型的节点（如审批节点、条件分支节点），不进行模糊匹配
    // 必须精确匹配nodeId，这样可以确保只显示真正执行过的节点的执行信息
  }
  
  if (!nodeActivity) return null
  
  // 对于抄送节点，从comment中提取抄送接收人作为操作人
  let operator = nodeActivity.operator
  let operatorName = nodeActivity.operatorName
  
  if (nodeActivity.nodeType === 'CC' && nodeActivity.comment) {
    // 从comment中提取抄送接收人: "抄送通知，方式: SYSTEM，接收人: 1"
    const ccUserMatch = nodeActivity.comment.match(/接收人:\s*([^，,]+)/)
    if (ccUserMatch && ccUserMatch[1]) {
      operator = ccUserMatch[1].trim()
      // 重新获取抄送接收人的显示名称
      operatorName = getOperatorDisplayName(operator, undefined)
    }
  }
  
  return {
    startTime: nodeActivity.startTime,
    endTime: nodeActivity.endTime,
    duration: nodeActivity.duration,
    operator: operator,
    operatorName: operatorName || getOperatorDisplayName(operator, nodeActivity.operatorName),
    comment: nodeActivity.comment,
    nodeName: nodeActivity.nodeName,
    nodeType: nodeActivity.nodeType
  }
}

const getFlowStatus = (flow: any) => {
  const fromNode = processNodes.value.find(n => n.id === flow.from)
  const toNode = processNodes.value.find(n => n.id === flow.to)
  
  // 对于条件分支节点，需要特殊处理
  // 如果起点是条件分支节点且已完成，只有目标节点有执行记录的连线才是激活的
  if (fromNode?.type === 'CONDITIONAL_BRANCH' && fromNode?.status === 'completed') {
    // 检查目标节点是否有执行记录（即是否真正走了这条分支）
    if (toNode?.status === 'completed' || toNode?.status === 'current' || toNode?.status === 'rejected') {
      // 目标节点有执行记录，说明走了这条分支
      if (toNode?.status === 'completed' || toNode?.status === 'rejected') {
        return 'completed'
      } else if (toNode?.status === 'current') {
        return 'active'
      }
    }
    // 目标节点是pending状态，说明没走这条分支
    return 'pending'
  }
  
  // 常规节点的连线状态判断
  if (fromNode?.status === 'completed' && toNode?.status === 'completed') {
    return 'completed'
  } else if (fromNode?.status === 'completed' && toNode?.status === 'rejected') {
    return 'completed'
  } else if (fromNode?.status === 'completed' && toNode?.status === 'current') {
    return 'active'
  } else if (fromNode?.status === 'current') {
    return 'pending'
  }
  
  return 'pending'
}

const calculateNodePosition = (node: any, allNodes: any[]) => {
  // 优先使用流程定义中保存的position，保持和设计器一致
  if (node.position) {
    return {
      x: node.position.x,
      y: node.position.y
    }
  }
  
  // 如果没有保存位置，使用自动布局作为fallback
  const index = allNodes.findIndex(n => n.id === node.id)
  const spacing = 280
  const startX = 100
  const startY = 200
  
  if (node.type === 'START') {
    return { x: startX, y: startY }
  } else if (node.type === 'END') {
    return { x: startX + (allNodes.length - 1) * spacing, y: startY }
  } else {
    return { x: startX + index * spacing, y: startY }
  }
}

const getNodeIcon = (type: string) => {
  const iconMap: Record<string, any> = {
    START: VideoPlay,
    END: Check,
    APPROVAL: User,
    CONDITIONAL_BRANCH: Connection
  }
  return iconMap[type] || Document
}

const getNodeTypeName = (type: string) => {
  const typeMap: Record<string, string> = {
    START: '开始节点',
    END: '结束节点',
    APPROVAL: '审批节点',
    CONDITIONAL_BRANCH: '条件分支'
  }
  return typeMap[type] || type
}

const getStatusText = (status: string) => {
  const statusMap: Record<string, string> = {
    pending: '未开始',
    current: '进行中',
    completed: '已完成',
    rejected: '已拒绝'
  }
  return statusMap[status] || '未知'
}

const getStatusTagType = (status: string) => {
  const typeMap: Record<string, string> = {
    pending: 'info',
    current: 'warning',
    completed: 'success',
    rejected: 'danger'
  }
  return typeMap[status] || 'info'
}

const getFlowColor = (flow: ProcessFlow) => {
  const colorMap: Record<string, string> = {
    completed: '#10b981',
    active: '#3b82f6',
    pending: '#d1d5db'
  }
  return colorMap[flow.status] || '#d1d5db'
}

const getFlowWidth = (flow: ProcessFlow) => {
  return flow.status === 'completed' || flow.status === 'active' ? 3 : 2
}

const getFlowMarker = (flow: ProcessFlow) => {
  if (flow.status === 'completed') return 'url(#arrowhead-completed)'
  if (flow.status === 'active') return 'url(#arrowhead-current)'
  return 'url(#arrowhead)'
}

const getFlowPath = (flow: ProcessFlow) => {
  const fromNode = processNodes.value.find(n => n.id === flow.from)
  const toNode = processNodes.value.find(n => n.id === flow.to)
  
  if (!fromNode || !toNode) return ''
  
  const fromPos = {
    x: fromNode.position.x + 180, // 节点右边
    y: fromNode.position.y + 40   // 节点中间
  }
  const toPos = {
    x: toNode.position.x,         // 节点左边
    y: toNode.position.y + 40     // 节点中间
  }
  
  const dx = toPos.x - fromPos.x
  const dy = toPos.y - fromPos.y
  
  // 创建贝塞尔曲线
  const controlDistance = Math.max(Math.abs(dx) * 0.3, 50)
  const cp1x = fromPos.x + controlDistance
  const cp1y = fromPos.y
  const cp2x = toPos.x - controlDistance
  const cp2y = toPos.y
  
  return `M ${fromPos.x} ${fromPos.y} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${toPos.x} ${toPos.y}`
}

const handleNodeClick = (node: ProcessNode) => {
  selectedNode.value = node
  showNodeDetail.value = true
}

const closeNodeDetail = () => {
  showNodeDetail.value = false
  selectedNode.value = null
}

const toggleFullscreen = () => {
  if (!isFullscreen.value) {
    // 进入全屏模式
    if (diagramContainer.value?.requestFullscreen) {
      diagramContainer.value.requestFullscreen()
      isFullscreen.value = true
      diagramHeight.value = window.innerHeight - 200
    }
  } else {
    // 退出全屏模式
    if (document.exitFullscreen) {
      document.exitFullscreen()
      isFullscreen.value = false
      diagramHeight.value = 500
    }
  }
}

const refreshDiagram = () => {
  // 根据节点的实际位置计算画布大小
  const nodes = processNodes.value
  if (nodes.length > 0) {
    // 找到最右边和最下边的节点位置
    const maxX = Math.max(...nodes.map(n => n.position.x)) + 250 // 节点宽度180 + 余量
    const maxY = Math.max(...nodes.map(n => n.position.y)) + 150 // 节点高度80 + 余量
    
    canvasSize.width = Math.max(1200, maxX)
    canvasSize.height = Math.max(500, maxY)
    diagramHeight.value = isFullscreen.value ? window.innerHeight - 200 : Math.min(600, canvasSize.height)
  }
}

const formatTime = (time?: string) => {
  if (!time) return '-'
  return new Date(time).toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const formatDuration = (duration?: number) => {
  if (!duration || duration === 0) return '瞬时'
  
  const seconds = Math.floor(duration / 1000)
  const minutes = Math.floor(seconds / 60)
  const hours = Math.floor(minutes / 60)
  const days = Math.floor(hours / 24)
  
  if (days > 0) {
    return `${days}天${hours % 24}小时`
  } else if (hours > 0) {
    return `${hours}小时${minutes % 60}分钟`
  } else if (minutes > 0) {
    return `${minutes}分钟${seconds % 60}秒`
  } else {
    return `${seconds}秒`
  }
}

// 加载用户数据
const loadUsers = async () => {
  try {
    console.log('[流程进度图] 开始加载用户数据...')
    const result = await userApi.getEnabledUsers()
    const users = result.data || []
    console.log('[流程进度图] 加载到的用户数据:', users)
    
    // 构建用户ID到用户信息的映射
    const newUserMap = new Map<number, User>()
    users.forEach((user: User) => {
      newUserMap.set(user.id, user)
      console.log(`[流程进度图] 添加用户到Map: ID=${user.id}, realName=${user.realName}, username=${user.username}`)
    })
    userMap.value = newUserMap
    console.log('[流程进度图] 用户Map构建完成，总数:', userMap.value.size)
  } catch (error) {
    console.error('加载用户数据失败:', error)
  }
}

// 获取操作员显示名称
const getOperatorDisplayName = (operator: string | number | undefined, operatorName?: string): string => {
  console.log(`[getOperatorDisplayName] 输入参数: operator=${operator}, operatorName=${operatorName}`)
  console.log(`[getOperatorDisplayName] userMap大小: ${userMap.value.size}`)
  
  // 如果已经有operatorName，直接返回
  if (operatorName && operatorName.trim()) {
    console.log(`[getOperatorDisplayName] 使用operatorName: ${operatorName}`)
    return operatorName
  }
  
  if (!operator) {
    console.log(`[getOperatorDisplayName] operator为空，返回"系统"`)
    return '系统'
  }
  
  // 尝试从用户映射中获取用户名
  const userId = typeof operator === 'string' ? parseInt(operator) : operator
  console.log(`[getOperatorDisplayName] 解析后的userId: ${userId}, isNaN: ${isNaN(userId)}`)
  
  if (!isNaN(userId)) {
    const user = userMap.value.get(userId)
    console.log(`[getOperatorDisplayName] userMap查询结果:`, user)
    
    if (user) {
      const displayName = user.realName || user.username
      console.log(`[getOperatorDisplayName] 返回用户名: ${displayName}`)
      return displayName
    } else {
      console.log(`[getOperatorDisplayName] userMap中找不到userId=${userId}的用户`)
      console.log(`[getOperatorDisplayName] userMap所有用户IDs:`, Array.from(userMap.value.keys()))
    }
  }
  
  // 如果找不到用户，返回原值
  console.log(`[getOperatorDisplayName] 返回原值: ${operator.toString()}`)
  return operator.toString()
}

// 生命周期
onMounted(() => {
  // 加载用户数据
  loadUsers()
  
  // 根据节点的实际位置计算画布大小
  const nodes = processNodes.value
  if (nodes.length > 0) {
    // 找到最右边和最下边的节点位置
    const maxX = Math.max(...nodes.map(n => n.position.x)) + 250
    const maxY = Math.max(...nodes.map(n => n.position.y)) + 150
    
    canvasSize.width = Math.max(1200, maxX)
    canvasSize.height = Math.max(500, maxY)
    diagramHeight.value = Math.min(600, canvasSize.height)
  }
})
</script>

<style scoped lang="scss">
.process-progress-diagram {
  width: 100%;
  background: white;
  border-radius: 0;
  border: none;
  box-shadow: none;
  overflow: hidden;
  
  &:fullscreen {
    border-radius: 0;
    border: none;
    box-shadow: none;
    height: 100vh;
    
    .diagram-content {
      height: calc(100vh - 120px) !important;
    }
    
    .diagram-header {
      padding: 16px 24px;
      
      .header-info .diagram-title {
        font-size: 18px;
      }
      
      .diagram-toolbar .el-button {
        font-size: 14px;
      }
    }
  }
}

.diagram-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  
  .header-info {
    display: flex;
    align-items: center;
    gap: 24px;
    
    .diagram-title {
      display: flex;
      align-items: center;
      gap: 8px;
      margin: 0;
      font-size: 16px;
      font-weight: 600;
      color: #303133;
      
      .el-icon {
        color: #409eff;
        font-size: 18px;
      }
    }
    
    .progress-summary {
      display: flex;
      align-items: center;
      gap: 12px;
      
      .progress-text {
        font-size: 14px;
        color: #606266;
        font-weight: 500;
        white-space: nowrap;
      }
    }
  }
  
  .diagram-toolbar {
    display: flex;
    gap: 8px;
    
    .el-button {
      font-size: 12px;
    }
  }
  
  .diagram-legend {
    display: flex;
    gap: 20px;
    
    .legend-item {
      display: flex;
      align-items: center;
      gap: 6px;
      font-size: 12px;
      color: #606266;
      font-weight: 500;
      
      .legend-color {
        width: 12px;
        height: 12px;
        border-radius: 2px;
        
        &.pending {
          background: #e4e7ed;
        }
        &.current {
          background: #409eff;
        }
        &.completed {
          background: #67c23a;
        }
        &.rejected {
          background: #f56c6c;
        }
      }
    }
  }
}

.diagram-content {
  position: relative;
  overflow: auto;
  background: #ffffff;
  scrollbar-width: none;
}

.diagram-content::-webkit-scrollbar {
  display: none;
}

.canvas-content {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 400px;
  background: #ffffff;
}

.progress-node {
  position: absolute;
  width: 180px;
  min-height: 80px;
  background: white;
  border: 2px solid #e5e7eb;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
  
  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
  }
  
  // 状态样式
  &.status-pending {
    border-color: #e4e7ed;
    
    .node-header {
      background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
      color: #909399;
    }
  }
  
  &.status-current {
    border-color: #409eff;
    box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
    
    .node-header {
      background: linear-gradient(135deg, #409eff 0%, #337ecc 100%);
      color: white;
    }
  }
  
  &.status-completed {
    border-color: #67c23a;
    box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
    
    .node-header {
      background: linear-gradient(135deg, #67c23a 0%, #529b2e 100%);
      color: white;
    }
  }
  
  &.status-rejected {
    border-color: #f56c6c;
    box-shadow: 0 4px 12px rgba(245, 108, 108, 0.3);
    
    .node-header {
      background: linear-gradient(135deg, #f56c6c 0%, #dd6161 100%);
      color: white;
    }
  }
}

.node-header {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  
  .node-icon-wrapper {
    position: relative;
    margin-right: 12px;
    
    .node-icon {
      font-size: 18px;
    }
    
    .status-indicator {
      position: absolute;
      top: -6px;
      right: -6px;
      width: 16px;
      height: 16px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      
      .status-icon {
        font-size: 10px;
        
        &.completed {
          color: white;
          background: #67c23a;
          border-radius: 50%;
          padding: 2px;
        }
        
        &.rejected {
          color: white;
          background: #f56c6c;
          border-radius: 50%;
          padding: 2px;
        }
        
        &.current {
          color: #409eff;
          animation: spin 1s linear infinite;
        }
        
        &.pending {
          color: #909399;
        }
      }
    }
  }
  
  .node-info {
    flex: 1;
    min-width: 0;
    
    .node-title {
      display: block;
      font-weight: 600;
      font-size: 13px;
      line-height: 1.2;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      margin-bottom: 2px;
    }
    
    .node-id {
      display: block;
      font-size: 10px;
      opacity: 0.8;
      font-family: 'Monaco', 'Consolas', monospace;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    .node-assignee {
      display: block;
      font-size: 11px;
      color: #409eff;
      font-weight: 500;
      margin-top: 2px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}

.execution-info {
  padding: 8px 16px;
  background: rgba(0, 0, 0, 0.02);
  
  .execution-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 4px;
    font-size: 11px;
    color: #606266;
    
    &:last-child {
      margin-bottom: 0;
    }
    
    .el-icon {
      font-size: 12px;
      color: #909399;
    }
    
    span {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}

.assignee-info {
  padding: 8px 16px;
  background: rgba(64, 158, 255, 0.05);
  border-top: 1px solid rgba(64, 158, 255, 0.1);
  
  .assignee-row {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: #409eff;
    font-weight: 500;
    
    .el-icon {
      font-size: 12px;
      color: #409eff;
    }
    
    span {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}

.node-status-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  
  .status-tag {
    font-size: 10px;
    padding: 2px 6px;
    border-radius: 10px;
    font-weight: 600;
  }
}

.flows-svg {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 1;
  
  .flow-line {
    stroke-linecap: round;
    transition: all 0.3s ease;
    
    &.completed {
      stroke-dasharray: none;
    }
    
    &.active {
      stroke-dasharray: 8,4;
      animation: flow-animation 1s linear infinite;
    }
    
    &.pending {
      opacity: 0.4;
    }
  }
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes flow-animation {
  from { stroke-dashoffset: 0; }
  to { stroke-dashoffset: 12; }
}

// 节点详情弹窗样式
.node-detail-content {
  .detail-section {
    margin-bottom: 24px;
    
    h4 {
      margin: 0 0 16px 0;
      color: #303133;
      font-size: 16px;
      font-weight: 600;
      border-bottom: 1px solid #ebeef5;
      padding-bottom: 8px;
    }
  }
  
  .comment-content {
    max-height: 100px;
    overflow-y: auto;
    white-space: pre-wrap;
    word-break: break-all;
    color: #606266;
    line-height: 1.4;
    background: #f5f7fa;
    padding: 8px 12px;
    border-radius: 6px;
    border-left: 3px solid #409eff;
  }
  
  .no-execution-info {
    text-align: center;
    padding: 40px 0;
  }
}

// 响应式设计
@media (max-width: 768px) {
  .diagram-header {
    flex-direction: column;
    gap: 16px;
    align-items: flex-start;
    
    .header-info {
      flex-direction: column;
      align-items: flex-start;
      gap: 12px;
    }
    
    .diagram-legend {
      flex-wrap: wrap;
      gap: 12px;
    }
  }
  
  .progress-node {
    width: 160px;
    
    .node-header {
      padding: 10px 12px;
      
      .node-info .node-title {
        font-size: 12px;
      }
    }
  }
}
</style>
